package com.spzx.channel.service.impl;

import com.alibaba.fastjson2.JSON;
import com.spzx.channel.domain.ItemVo;
import com.spzx.channel.service.ItemService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.Product;
import com.spzx.product.api.domain.ProductDetails;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuPrice;
import com.spzx.product.api.domain.vo.SkuStockVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author Haoran Sun
 * @since 2024/07/25
 */

@Service
@Slf4j
public class ItemServiceImpl implements ItemService {

    @Resource
    private RemoteProductService remoteProductService;
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private RedissonClient redissonClient;


    @Override
    public ItemVo item(Long skuId) {

        ItemVo itemVo = new ItemVo();
        //使用布隆过滤器
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("sku:bloom:filter");
        if (!bloomFilter.contains(skuId)) {
            log.error("用户查询商品sku不存在：{}", skuId);
            //查询数据不存在直接返回空对象
            throw new ServiceException("用户查询商品sku不存在");
        }

        CompletableFuture<Long> skuFuture = CompletableFuture.supplyAsync(() -> {
                    //获取商品sku信息
                    R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
                    if (R.isError(productSkuResult)) throw new ServiceException("获取商品sku信息失败");
                    Long productId = productSkuResult.getData().getProductId();
                    if (productId == null) {
                        throw new ServiceException("获取商品信息失败，服务器数据存在问题");
                    }
                    itemVo.setProductSku(productSkuResult.getData());
                    return productId;
                }, threadPoolExecutor
        );

        CompletableFuture<Void> productFuture = skuFuture.thenAcceptAsync((productId) -> {
            //获取商品信息
            R<Product> productResult = remoteProductService.getProduct(productId, SecurityConstants.INNER);
            if (R.isError(productResult)) throw new ServiceException("获取商品信息失败");
            itemVo.setProduct(productResult.getData());
            //设置商品轮播图列表
            itemVo.setSliderUrlList(Arrays.stream(productResult.getData().getSliderUrls().split(",")).toList());
            //设置商品规格信息
            itemVo.setSpecValueList(JSON.parseArray(productResult.getData().getSpecValue()));
        }, threadPoolExecutor);
        CompletableFuture<Void> skuPriceFuture = CompletableFuture.runAsync(() -> {
            //获取商品sku的价格信息
            R<SkuPrice> skuPriceResult = remoteProductService.getSkuPrice(skuId, SecurityConstants.INNER);
            if (R.isError(skuPriceResult)) throw new ServiceException("获取商品sku价格信息失败");
            itemVo.setSkuPrice(skuPriceResult.getData());
        }, threadPoolExecutor);
        CompletableFuture<Void> productDetailsFuture = skuFuture.thenAcceptAsync((productId) -> {
            //商品详情图片列表
            R<ProductDetails> productDetailResult = remoteProductService.getProductDetails(productId, SecurityConstants.INNER);
            if (R.isError(productDetailResult)) throw new ServiceException("获取商品详情图片列表失败");
            itemVo.setDetailsImageUrlList(Arrays.stream(productDetailResult.getData().getImageUrls().split(",")).toList());
        }, threadPoolExecutor);
        CompletableFuture<Void> skuStockFuture = CompletableFuture.runAsync(() -> {
            //商品库存信息
            R<SkuStockVo> skuStockResult = remoteProductService.getSkuStock(skuId, SecurityConstants.INNER);
            if (R.isError(skuStockResult)) throw new ServiceException("获取商品库存信息失败");
            itemVo.setSkuStockVo(skuStockResult.getData());
        }, threadPoolExecutor);
        CompletableFuture<Void> productSkuFuture = skuFuture.thenAcceptAsync((productId) -> {
            //根据商品id查询 商品规格对应商品skuId信息
            R<Map<String, Long>> skuSpecValueResult = remoteProductService.getSkuSpecValue(productId, SecurityConstants.INNER);
            if (R.isError(skuSpecValueResult)) throw new ServiceException("获取商品规格对应商品skuId信息失败");
            itemVo.setSkuSpecValueMap(skuSpecValueResult.getData());
        }, threadPoolExecutor);

        CompletableFuture.allOf(
                skuFuture,
                productFuture,
                skuPriceFuture,
                productDetailsFuture,
                skuStockFuture,
                productSkuFuture
        ).join();
        return itemVo;
    }
}
